package com.jt.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

/**
 * @ClassName TokenConfig
 * @Description 配置令牌的生成，存储策略，验签方式（令牌合法性）
 * @Author Jiyao
 * @DATE 2021-11-28 17:01
 * @Version 1.0
 **/
@Configuration
public class TokenConfig {
    /**
     * JWT令牌签名时使用的密钥(可以理解为盐值加密中的盐)
     * 1)生成的令牌需要这个密钥进行签名
     * 2)获得的令牌需要使用这个密钥进行验签（校验令牌合法性，是否被篡改）
     * @Date 17:08 2021/11/28
     * @Param
     * @return
     **/
    private static final String SIGNING_KEY = "auth";

    /**
     * 配置令牌的存储策略，对于oauth2规范中提供了如下策略：
     * 1)JdbcTokenStore(要求：需要将token存储到关系型数据库)
     * 2)RedisTokenStore(要求：需要将token存储到Redis数据库)
     * 3)JwtTokenStore(将产生的token信息存储到客户端，且token中可以以自包含的形式存储一些用户的信息
     * @Date 17:12 2021/11/28
     * @Param []
     * @return org.springframework.security.oauth2.provider.token.TokenStore
     **/
    @Bean
    public TokenStore tokenStore(){
        //采用JWT方式生成和存储令牌信息
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /**
     * 配置令牌的创建及解析方式
     * 基于此对象创建的令牌信息会封装到OAuth2AccessToken类型的对象中，后再存储到TokenStore对象，
     * 外界需要时，会从tokenStore中进行获取
     * @Date 17:19 2021/11/28
     * @Param []
     * @return org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter
     **/
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        //JWT令牌的构成：header(签名算法，令牌类型),payload(数据部分),Signing(签名)
        //这里的签名可以简单理解成加密，加密时会使用header中算法以及我们自己提供的密钥
        //密钥的使用是为了防止令牌被篡改。（密钥要保管好，要存储在服务端）
        //设置密钥
        jwtAccessTokenConverter.setSigningKey(SIGNING_KEY);
        return jwtAccessTokenConverter;
    }
}
